package com.zhang.controller.order;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhang.common.util.redis.RedisUtil;
import com.zhang.common.util.result.R;
import com.zhang.common.util.result.RUtils;
import com.zhang.discount.service.FlashSaleSkuService;
import com.zhang.order.dto.OrderISaveItemDto;
import com.zhang.order.dto.OrderItemSearchDTO;
import com.zhang.order.dto.OrderSaveDto;
import com.zhang.order.entity.Order;
import com.zhang.order.entity.OrderItem;
import com.zhang.order.service.IOrderItemService;
import com.zhang.order.service.IOrderService;
import com.zhang.order.vo.OrderAppraiseVo;
import com.zhang.order.vo.OrderDetailVo;
import com.zhang.order.vo.UserEarningsVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 订单 前端控制器
 * </p>
 *
 * @author 创世神
 * @since 2023-12-05
 */
@RestController
@RequestMapping("/order")
@SaCheckLogin
public class OrderController {
    @Autowired
    private RedisUtil redisUtil;

    private final String orderKeyPrefix = "order:token:";
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderItemService orderItemService;
    @Autowired
    private FlashSaleSkuService flashSaleSkuService;


    /**
     * 获取订单防重复提交令牌
     *
     * @return {@link R}
     */
    @GetMapping("token")
    public R getOrderToken() {
        String s = UUID.randomUUID().toString();
        long id = StpUtil.getLoginIdAsLong();
//       以用户id作为key,
        redisUtil.set(orderKeyPrefix + id, s, 30, TimeUnit.MINUTES);
        HashMap<String, String> map = new HashMap<>();
        map.put("token", s);
        return RUtils.successData(map);
    }

    /**
     * 提交订单
     *
     * @param order
     * @return {@link R}
     */
    @PostMapping("save")
    public R saveOrder(@RequestBody OrderSaveDto order) {
        long id = StpUtil.getLoginIdAsLong();

//        使用lua脚本保证原子性 返回0 失败 返回1 成功
        String script = "if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
        RedisTemplate<String, Object> redisTemplate = redisUtil.getRedisTemplate();
        Long result = redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Collections.singletonList(orderKeyPrefix + id), order.getToken());
        assert result!=null;
        if (result == 1L) {
//            令牌验证成功
//            如果是秒杀活动订单，扣除redis中的库存并且返回价格
            if (order.getOrderType()==1){
                for (OrderISaveItemDto orderISaveItemDto : order.getOrderISaveItemDtos()) {
                  BigDecimal price= flashSaleSkuService.buyFlashSaleSku(orderISaveItemDto.getSkuId().toString(),orderISaveItemDto.getBuyNumber(),orderISaveItemDto.getSkuToken());
                    if (price == null) {
                        return RUtils.err("手慢了哦，秒杀失败");
                    }
                    orderISaveItemDto.setPrice(price);
                }
            }
            String orderId = orderService.saveOrder(order);
            return RUtils.successData(orderId);
        } else {
//            令牌验证失败
            return RUtils.err("订单提交异常！");
        }
    }

    /**
     * 获取订单详情
     *
     * @param orderId
     * @return {@link R}
     */
    @GetMapping("get/orderInfo")
    public R getOrderInfo(Long orderId) {
        OrderDetailVo orderinfo = orderService.getOrderInfo(orderId);
        return RUtils.successData(orderinfo);
    }

    /**
     * 查询当前用户的订单列表
     *
     * @param queryMap status,pageNum,pageSize
     * @return {@link R}
     */
    @GetMapping("get/orderList")
    public R getOrderListByStatus(@RequestParam Map<String, String> queryMap) {
        Page orderList = orderService.listByStatusAndUser(queryMap);
        return RUtils.successData(orderList);
    }

    /**
     * 订单收货
     *
     * @param orderId
     * @return {@link R}
     */
    @PostMapping("receive")
    public R receiveOrder(@RequestParam String orderId) {
        try {
            orderService.receive(Long.valueOf(orderId));
        } catch (RuntimeException e) {
            return RUtils.err("订单异常");
        }
        return RUtils.successMsg("收货成功！");
    }

    /**
     * 修改订单为发货状态
     *
     * @param OrderId
     * @return {@link R}
     */
    @PostMapping("send")
    public R send(@RequestParam String OrderId) {
        try {
            orderService.updateOrderToSend(OrderId);
        } catch (RuntimeException e) {
            return RUtils.err("订单异常!");
        }
        return RUtils.successMsg("修改成功!");
    }

    @PutMapping
    public R update(@RequestBody Order order) {
        orderService.updateById(order);
        return RUtils.successMsg("修改成功!");
    }

    /**
     * 获取订单评价vo
     *
     * @param orderId
     * @return {@link R}
     */
    @GetMapping("orderAppraiseVo")
    public R getOrderAppraiseVo(@RequestParam String orderId) {
        List<OrderAppraiseVo> orderAppraises = orderService.getOrderAppraise(orderId);
        return RUtils.successData(orderAppraises);
    }

    /**
     * 获取一个商家的营业额信息
     *
     * @return {@link R}
     */
    @GetMapping("earnings")
    public R userEarnings() {
        long loginUser = StpUtil.getLoginIdAsLong();
        UserEarningsVO userEarningsVO = orderService.userEarnings(loginUser);
        return RUtils.successData(userEarningsVO);
    }

    /**
     * 获取商家的订单项信息列表
     *
     * @param dto
     * @return {@link R}
     */
    @GetMapping("orderItem/page")
    public R getBusinessOrderItems(OrderItemSearchDTO dto) {
        IPage<OrderItem> orderItems = orderItemService.getBusinessOrderItems(dto);
        return RUtils.successData(orderItems);
    }
}
